﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Input;

namespace Gmantis.Controls
{
    internal sealed class CommandBindingCollection : IList, ICollection, IEnumerable
    {
        // Fields
        private List<CommandBinding> _innerCBList;

        // Methods
        public CommandBindingCollection()
        {
        }

        public CommandBindingCollection(IList commandBindings)
        {
            if ((commandBindings != null) && (commandBindings.Count > 0))
            {
                this.AddRange(commandBindings);
            }
        }

        public int Add(CommandBinding commandBinding)
        {
            if (commandBinding == null)
            {
                throw new NotSupportedException("CollectionOnlyAcceptsCommandBindings");
            }
            if (this._innerCBList == null)
            {
                this._innerCBList = new List<CommandBinding>(1);
            }
            this._innerCBList.Add(commandBinding);
            return 0;
        }

        public void AddRange(ICollection collection)
        {
            if (collection == null)
            {
                throw new ArgumentNullException("collection");
            }
            if (collection.Count > 0)
            {
                if (this._innerCBList == null)
                {
                    this._innerCBList = new List<CommandBinding>(collection.Count);
                }
                IEnumerator enumerator = collection.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    CommandBinding current = enumerator.Current as CommandBinding;
                    if (current == null)
                    {
                        throw new NotSupportedException("CollectionOnlyAcceptsCommandBindings");
                    }
                    this._innerCBList.Add(current);
                }
            }
        }

        public void Clear()
        {
            if (this._innerCBList != null)
            {
                this._innerCBList.Clear();
                this._innerCBList = null;
            }
        }

        public bool Contains(CommandBinding commandBinding)
        {
            return (((this._innerCBList != null) && (commandBinding != null)) && this._innerCBList.Contains(commandBinding));
        }

        public void CopyTo(CommandBinding[] commandBindings, int index)
        {
            if (this._innerCBList != null)
            {
                this._innerCBList.CopyTo(commandBindings, index);
            }
        }

        internal CommandBinding FindMatch(ICommand command, ref int index)
        {
            while (index < this.Count)
            {
                CommandBinding binding = this[index++];
                if (binding.Command == command)
                {
                    return binding;
                }
            }
            return null;
        }

        public IEnumerator GetEnumerator()
        {
            if (this._innerCBList != null)
            {
                return this._innerCBList.GetEnumerator();
            }
            List<CommandBinding> list = new List<CommandBinding>(0);
            return list.GetEnumerator();
        }

        public int IndexOf(CommandBinding value)
        {
            if (this._innerCBList == null)
            {
                return -1;
            }
            return this._innerCBList.IndexOf(value);
        }

        public void Insert(int index, CommandBinding commandBinding)
        {
            if (commandBinding == null)
            {
                throw new NotSupportedException("CollectionOnlyAcceptsCommandBindings");
            }
            if (this._innerCBList != null)
            {
                this._innerCBList.Insert(index, commandBinding);
            }
        }

        public void Remove(CommandBinding commandBinding)
        {
            if ((this._innerCBList != null) && (commandBinding != null))
            {
                this._innerCBList.Remove(commandBinding);
            }
        }

        public void RemoveAt(int index)
        {
            if (this._innerCBList != null)
            {
                this._innerCBList.RemoveAt(index);
            }
        }

        void ICollection.CopyTo(Array array, int index)
        {
            if (this._innerCBList != null)
            {
                this._innerCBList.CopyTo((CommandBinding[])array, index);
            }
        }

        int IList.Add(object commandBinding)
        {
            return this.Add(commandBinding as CommandBinding);
        }

        bool IList.Contains(object key)
        {
            return this.Contains(key as CommandBinding);
        }

        int IList.IndexOf(object value)
        {
            CommandBinding binding = value as CommandBinding;
            if (binding == null)
            {
                return -1;
            }
            return this.IndexOf(binding);
        }

        void IList.Insert(int index, object value)
        {
            this.Insert(index, value as CommandBinding);
        }

        void IList.Remove(object commandBinding)
        {
            this.Remove(commandBinding as CommandBinding);
        }

        // Properties
        public int Count
        {
            get
            {
                if (this._innerCBList == null)
                {
                    return 0;
                }
                return this._innerCBList.Count;
            }
        }

        public bool IsFixedSize
        {
            get
            {
                return this.IsReadOnly;
            }
        }

        public bool IsReadOnly
        {
            get
            {
                return false;
            }
        }

        public bool IsSynchronized
        {
            get
            {
                return ((this._innerCBList != null) && ((ICollection)this._innerCBList).IsSynchronized);
            }
        }

        public CommandBinding this[int index]
        {
            get
            {
                if (this._innerCBList == null)
                {
                    return null;
                }
                return this._innerCBList[index];
            }
            set
            {
                if (this._innerCBList != null)
                {
                    this._innerCBList[index] = value;
                }
            }
        }

        public object SyncRoot
        {
            get
            {
                return this;
            }
        }

        object IList.this[int index]
        {
            get
            {
                return this[index];
            }
            set
            {
                CommandBinding binding = value as CommandBinding;
                if (binding == null)
                {
                    throw new NotSupportedException("CollectionOnlyAcceptsCommandBindings");
                }
                this[index] = binding;
            }
        }
    }
}
